From: Ian Campbell Date: Mon, 2 Dec 2013 11:11:40 +0000 (+0000) Subject: xen: arm: avoid truncation in mfn to paddr conversions X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~5824 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=9ca423b1fb164a30f40bfacc6c03106fbe1945b1;p=xen.git xen: arm: avoid truncation in mfn to paddr conversions Although MFNs are 64-bit in the hypercall ABI they are most often unsigned long internally, and therefore be 32-bit on arm32. Physical addresses are always 64-bit via paddr_t. This means that the common "mfn << PAGE_SHIFT" pattern risks losing some of the top bits of the address is high enough. This need not imply a high amount of RAM, just a sparse physical address map. The correct form is ((paddr_t)mfn)< Acked-by: Julien Grall Acked-by: Stefano Stabellini --- diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 99e785aaaa..7c855cbc7d 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -84,8 +84,8 @@ static void allocate_memory_11(struct domain *d, struct kernel_info *kinfo) panic("Failed to allocate contiguous memory for dom0\n"); spfn = page_to_mfn(pg); - start = spfn << PAGE_SHIFT; - size = (1 << order) << PAGE_SHIFT; + start = pfn_to_paddr(spfn); + size = pfn_to_paddr((1 << order)); // 1:1 mapping printk("Populate P2M %#"PRIx64"->%#"PRIx64" (1:1 mapping for dom0)\n", diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index 2de7dc7d0f..8189915132 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -1032,10 +1032,10 @@ static int xenmem_add_to_physmap_one( return rc; } - maddr = p2m_lookup(od, idx << PAGE_SHIFT); + maddr = p2m_lookup(od, pfn_to_paddr(idx)); if ( maddr == INVALID_PADDR ) { - dump_p2m_lookup(od, idx << PAGE_SHIFT); + dump_p2m_lookup(od, pfn_to_paddr(idx)); rcu_unlock_domain(od); return -EINVAL; } diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index af32511f56..1d5c841014 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -296,18 +296,20 @@ int guest_physmap_add_page(struct domain *d, unsigned long mfn, unsigned int page_order) { - return create_p2m_entries(d, INSERT, gpfn << PAGE_SHIFT, - (gpfn + (1<> PAGE_SHIFT; } diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index d252131e1a..0795eb9a64 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -409,7 +409,8 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) do { - e = consider_modules(ram_start, ram_end, xenheap_pages<= virt_to_maddr(&_start)) && \ - (((mfn) << PAGE_SHIFT) <= virt_to_maddr(&_end))) + ((pfn_to_paddr(mfn) >= virt_to_maddr(&_start)) && \ + (pfn_to_paddr(mfn) <= virt_to_maddr(&_end))) #define page_get_owner(_p) (_p)->v.inuse.domain #define page_set_owner(_p,_d) ((_p)->v.inuse.domain = (_d))